home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / bbs / s342q16.lha / sysdep4.c < prev    next >
C/C++ Source or Header  |  1996-08-29  |  15KB  |  455 lines

  1. /**
  2.   Citadel Message procesing routines
  3. **/
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include "ctdl.h"
  8.  
  9. extern CONFIG      cfg;   /* Lots an lots of variables    */
  10. extern logBuffer   logBuf;    /* Person buffer    */
  11.  
  12. struct variables
  13.   {
  14.   char *ourname;     /* name of the variable */
  15.   char type;         /* type of variable */
  16.   union
  17.     {
  18.     UNS_16 *where; /* offset into codeBuf */
  19.     char   *addr;  /* char data pointer */
  20.     void   (*func1)(char *);
  21.     char  *(*func2)(void);
  22.     long   (*func3)(void);
  23.     long   id;
  24.     } object;
  25.   };
  26.  
  27.  
  28. #define CHAR_PTR    0   /* item is a character string pointer */
  29. #define CFGB_PTR    1   /* item is offset into codeBuf        */
  30. #define FUNC1_PT    2   /* Function: void  (func1 *)(char *target) */
  31. #define FUNC2_PT    3   /* Function: char *(func2 *)(void) */
  32. #define FUNC3_PT    4   /* Function: long  (func3 *)(void) */
  33. #define IARG1_PT    5   /* Argument # 1 Integer    */
  34. #define SARG1_PT    6   /* Argument # 1 String ptr */
  35. #define IARG2_PT    7   /* Argument # 2 Integer    */
  36. #define SARG2_PT    8   /* Argument # 2 String ptr */
  37. #define IARG3_PT    9   /* Argument # 3 Integer    */
  38. #define SARG3_PT   10   /* Argument # 3 String ptr */
  39. #define NEW_LINE   11   /* special: add a new line and space*/
  40. #define INT_PTR    12   /* integer data item */
  41. #define SPACE_CH   13   /* special: add a space */
  42. #define BACK_SPC   14   /* special: add a ^H character to the messge */
  43. extern char *SysVers;
  44. extern char  *VERSION;
  45. extern char lastuser[];
  46.  
  47. #define MAXVARS (29)
  48.  
  49. static long message_sector_value(void);
  50.  
  51. struct variables variable[MAXVARS] =
  52.   {
  53.     { "variant",     CHAR_PTR, (unsigned short *)&VARIANT_NAME    },
  54.     { "version",     CHAR_PTR, (unsigned short *)&VERSION_NAME    },
  55.     { "sysvers",     CHAR_PTR, (unsigned short *)&SYSDEP_NAME     },
  56.     { "baseroom",    CFGB_PTR, (unsigned short *)&cfg.bRoom       },
  57.     { "sysop",       CHAR_PTR, (unsigned short *)&cfg.SysopName   }, /* 5 */
  58.     { "nodetitle",   CFGB_PTR,                  &cfg.nodeTitle    },
  59.     { "nodename",    CFGB_PTR,                  &cfg.nodeName     },
  60.     { "nodedomain",  CFGB_PTR,                  &cfg.nodeDomain   },
  61.     { "nodeid",      CFGB_PTR,                  &cfg.nodeId       },
  62.     { "mainfloor",   CFGB_PTR,                  &cfg.MainFloor    }, /*10*/
  63.     { "curruser",    CHAR_PTR, (unsigned short *)&logBuf.lbname   },
  64.     { "ulprotocols", FUNC1_PT, (unsigned short *)UpProtsEnglish   },
  65.     { "dlprotocols", FUNC1_PT, (unsigned short *)DownProtsEnglish },
  66.     { "doorlist",    FUNC1_PT, (unsigned short *)DoorHelpListing  },
  67.     { "lastuser",    CHAR_PTR, (unsigned short *)&lastuser        },/*15*/
  68.     { "privileges",  FUNC2_PT, (unsigned short *)Display_Privledges},
  69.     { "callcount",   FUNC3_PT, (unsigned short *)Get_Call_Count   },
  70.     { "ia1",         IARG1_PT, (unsigned short *) 1               },
  71.     { "sa1",         SARG1_PT, (unsigned short *) 1               },
  72.     { "ia2",         IARG2_PT, (unsigned short *) 2               }, /*20*/
  73.     { "sa2",         SARG2_PT, (unsigned short *) 2               },
  74.     { "ia3",         IARG3_PT, (unsigned short *) 3               },
  75.     { "sa3",         SARG3_PT, (unsigned short *) 3               },
  76.     { "currtime",    FUNC2_PT, (unsigned short *)Current_Time     },
  77.     { "currdate",    FUNC2_PT, (unsigned short *)formDate         }, /*25*/
  78.     { "messages",    FUNC3_PT, (unsigned short *)message_sector_value },
  79.     { "s",           SPACE_CH, NULL                               },
  80.     { "b",           BACK_SPC, NULL                               },
  81.     { "n",           NEW_LINE, NULL                               }
  82.  
  83. /***
  84.     { "lastcall"    CHAR_PTR,(unsigned short *) NULL },
  85.     { "events"      CHAR_PTR(unsigned short *) NULL },
  86.     { "rooms"       CHAR_PTR(unsigned short *) NULL },
  87.     { "roomsused"   CHAR_PTR(unsigned short *) NULL },
  88.     { "lastmessage" CHAR_PTR(unsigned short *) NULL },
  89.     { "logs"        CHAR_PTR(unsigned short *) NULL },
  90.     { "logsused"    CHAR_PTR(unsigned short *) NULL },
  91.     { "lenmessage"  CHAR_PTR(unsigned short *) NULL },
  92. **/
  93.   };
  94.  
  95. struct  Cit_Msg
  96.   {
  97.   struct Cit_Msg *link;/* link to common hashed messages */
  98.   char MsgId[9];       /* Message Identifier */
  99.   char MsgText[72];    /* Message Text */
  100.   };
  101.  
  102. #define MAX_MSGS  ( 523 ) /* good sized prime number */
  103.  
  104. static struct Cit_Msg *Message_Table[MAX_MSGS];   /* dynamic message table */
  105.  
  106. /**
  107.   The message file is made up of a count of the messages
  108.   plus one line per message.  Each message is made up of a
  109.   message ID(8 characters), plus the actual text(71 characters or less).
  110. **/
  111.  
  112. static long message_sector_value()
  113.   {
  114.   return (long)cfg.maxMSector;
  115.   }
  116.  
  117.  
  118. static int Load_Items(FILE *fp);
  119. static int Hashed_Msg(char *text);
  120. void Load_Citadel_Messages(void);
  121.  
  122. static int Hashed_Msg(char *text)
  123.   {
  124.   int result;
  125.   int cnt;
  126.   for( result=0, cnt=0; text[cnt] != '\0'; cnt++)
  127.     result = ( result << 1 ) + toupper(text[cnt]);
  128.   result %= MAX_MSGS;
  129.   return result;
  130.   }
  131.  
  132. static int Load_Items(FILE *fp)
  133.   {
  134.   int cnt;
  135.   char *p;
  136.   char Text[200];        /* Message Text */
  137.   struct Cit_Msg *ptr;  /* hashed Entry Value */
  138.   struct Cit_Msg *tptr; /* hashed Entry Value for duplicate check */
  139.   /**
  140.     Get the ID, hash it, then add it to the table
  141.     File format:
  142.     # comment lines are ignored, and start with "#"
  143.     1      8       10                  79
  144.     IIIIIIII<space>TTTTTTTTTTTTTTTTTTTTTT<newline>
  145.   **/
  146.   while( fgets(Text,sizeof(Text),fp) )
  147.     {
  148.     if( strlen(Text) > 79 )
  149.       {
  150.       printf("WARNING: CIT_MESSAGE.SYS text line too long, Truncated:\n%s\n",Text);
  151.       Text[79] = '\0';
  152.       };
  153.     if( Text[0] == '#' )continue;                /* skip comment characters */
  154.     if( (p=strchr(Text,'\n')) != NULL)*p = '\0'; /* get rid of newline      */
  155.     Text[8] = '\0';
  156.     ptr = calloc(1,sizeof(struct Cit_Msg));     /* get an element          */
  157.     if( ptr == NULL)return 2;                   /* No memory available     */
  158.     strcpy(ptr->MsgId,   &Text[0]);
  159.     strcpy(ptr->MsgText, &Text[9]);             /* build entry             */
  160.     cnt        = Hashed_Msg(&Text[0]);
  161.     tptr       = Message_Table[cnt];
  162. /**
  163.   Look up the message to be sure we don't have a duplicate
  164. **/
  165.     while( tptr != NULL )
  166.       {
  167.       if( stricmp(tptr->MsgId, ptr->MsgId) == 0 )break;
  168.       tptr = tptr->link;
  169.       };
  170.     if( tptr != NULL )
  171.       printf("Error:  Duplicate Message Code(%s) in Cit_Message.Sys\n",Text);
  172.     ptr->link  = Message_Table[cnt];
  173.     Message_Table[cnt] = ptr;
  174.     };
  175.   return 0;
  176.   }
  177.  
  178. #define MAX_LINE (120)
  179.  
  180. extern MessageBuffer     msgBuf;
  181. static void Fix_Line(char *line, char *buffer, long arg1, long arg2, long arg3);
  182.  
  183. static void Fix_Line(char *line, char *buffer, long arg1, long arg2, long arg3)
  184.   {
  185.   struct variables *vptr;
  186.   char *ptr;
  187.   char *tmp;
  188.   long inttmp;
  189.   int index = strlen(buffer);
  190.   while( *line != '\0' )
  191.     {
  192.     if( *line == '^' )
  193.       {
  194.       int i;
  195.       ptr = ++line;
  196.       buffer[index] = '\0';
  197.       for( i=0; i < MAXVARS; i++)
  198.         {
  199.         vptr = &variable[i];
  200.         if( strncmp(vptr->ourname, ptr, strlen(vptr->ourname)) == 0)
  201.           {
  202.           switch (vptr->type)
  203.             {
  204.             case BACK_SPC: /* insert a backspace character in message */
  205.                buffer[index] = '\b';
  206.                break;
  207.             case NEW_LINE: /* put in a newline and space */
  208.               strcat(buffer,"\n ");
  209.               break;
  210.             case SPACE_CH: /* insert a space */
  211.               strcat(buffer," ");
  212.               break;
  213.             case CHAR_PTR: /* char pointer, direct access */
  214.               strcat(buffer,vptr->object.addr);
  215.               break;
  216.             case CFGB_PTR: /* make a char pointer, then direct access */
  217.               strcat(buffer,&cfg.codeBuf[*vptr->object.where]);
  218.               break;
  219.             case FUNC1_PT: /* call the function, direct to buffer */
  220.               (vptr->object.func1)(lbyte(buffer));
  221.               break;
  222.             case FUNC2_PT: /* call the function, direct access */
  223.               tmp = (vptr->object.func2)();
  224.               strcat(buffer, tmp );
  225.               break;
  226.             case FUNC3_PT: /* call the function, convert number into buffer */
  227.               inttmp = (vptr->object.func3)();
  228.               sprintf(lbyte(buffer),"%ld", inttmp );
  229.               break;
  230.             case INT_PTR:  /* integer argument */
  231.               sprintf(lbyte(buffer), "%ld, *vptr->object.addr");
  232.               break;
  233.             case IARG1_PT: /* argument in call */
  234.               sprintf(lbyte(buffer),"%ld",arg1);
  235.               break;
  236.             case SARG1_PT: /* argument is */
  237.               if( arg1 != NULL )sprintf(lbyte(buffer),"%s",arg1);
  238.               break;
  239.             case IARG2_PT: /* argument in call */
  240.               sprintf(lbyte(buffer),"%ld",arg2);
  241.               break;
  242.             case SARG2_PT: /* argument is */
  243.               if( arg1 != NULL )sprintf(lbyte(buffer),"%s",arg2);
  244.               break;
  245.             case IARG3_PT: /* argument in call */
  246.               sprintf(lbyte(buffer),"%ld",arg3);
  247.               break;
  248.             case SARG3_PT: /* argument is  */
  249.               if( arg1 != NULL )sprintf(lbyte(buffer),"%s",arg3);
  250.               break;
  251.  
  252.             };
  253.           line += strlen(vptr->ourname);
  254.           index = strlen(buffer);
  255.           break;
  256.           }
  257.         };
  258.       if( i == MAXVARS )buffer[index++] = *line++;
  259.       }
  260.     else buffer[index++] = *line++;
  261.     };
  262.   buffer[index] = '\0';
  263.   }
  264.  
  265. static struct Cit_Msg *Look_Up(char *code);
  266.  
  267. static struct Cit_Msg *Look_Up(char *code)
  268.   {
  269.   struct Cit_Msg *ptr;
  270.   ptr = Message_Table[Hashed_Msg(code)];
  271.   if( ptr ==  NULL )return NULL;
  272.   while( ptr != NULL )
  273.     {
  274.     if( stricmp(ptr->MsgId, code) == 0)return ptr;
  275.     ptr = ptr->link;
  276.     };
  277.   return NULL;
  278.   }
  279.  
  280. char *msgbuffer=NULL;   /* Initialized from available memory */
  281.  
  282. void Output_Citadel_Message(char *pcode,long arg1, long arg2, long arg3)
  283.   {
  284.   char code[9];
  285.   FILE *op;
  286.   char line[MAX_LINE];
  287.   struct Cit_Msg *ptr;
  288. /**
  289.   translate the code into a message
  290. **/
  291.   if( msgbuffer == NULL )    msgbuffer = GetDynamic(MAXTEXT);
  292.   strncpy(code,pcode,6);
  293.   code[6] = '\0';
  294.   strcat(code,expert ? "EX" : "NO");
  295.   code[8] = '\0';
  296.   ptr = Look_Up(code);     /* find the code or return NULL */
  297.   if( ptr == NULL && expert )
  298.     {
  299.     code[6] = 'N';
  300.     code[7] = 'O';
  301.     ptr =  Look_Up(code);
  302.     };
  303.   if( ptr == NULL )
  304.     {
  305.     mPrintf("\n ***Error Code %s\n",code);
  306.     }
  307.   else
  308.     {
  309.     if( ptr->MsgText[0] == '@')
  310.       {
  311.       if( (op=fopen(&ptr->MsgText[1],"r")) == NULL )
  312.         {
  313.         mPrintf("\n *** Error Code %s, filename:%s not found\n",code,&ptr->MsgText[1]);
  314.         }
  315.       else
  316.         {
  317.         msgbuffer[0] = '\0';
  318.         while (fgets(line, MAX_LINE, op) )
  319.           {
  320.           char *p;
  321.           if( (p=strchr(line,'\n')) != NULL)*p = '\0'; /* get rid of newline      */
  322.           Fix_Line(line,msgbuffer, arg1,arg2, arg3);
  323.           if( ( strlen(msgbuffer) + strlen(line) + 500 ) > MAXTEXT )
  324.             {
  325.             mPrintf("%s", msgbuffer);
  326.             msgbuffer[0] = '\0';
  327.             };
  328.           };
  329.         fclose(op);
  330.         };
  331.       }
  332.     else
  333.       {
  334.       msgbuffer[0] = '\0';
  335.       Fix_Line(ptr->MsgText,msgbuffer, arg1, arg2, arg3);
  336.       };
  337.     if( strlen(msgbuffer) > 0 ) mPrintf("%s",msgbuffer);
  338.  
  339.     }
  340.   }
  341.  
  342. void Load_Citadel_Messages()
  343.   {
  344.   int code;       /* Error Code */
  345.   char temp[80];  /* input filename  */
  346.   FILE *fp;       /* input file pointer */
  347. /*  SpecialMessage("Message Initialization"); */
  348.   makeSysName(temp,"Cit_Messages.sys", &cfg.msgArea);
  349.   if( (fp=fopen(temp,/* READ_TEXT*/ "r")) != NULL )
  350.     {
  351.     memset(Message_Table,'\0',sizeof(struct Cit_Msg *) * MAX_MSGS );
  352.     code = Load_Items( fp );
  353.     fclose(fp);
  354.     }
  355.   else code = 1;      /* file will not open */
  356.   if( code != 0 )
  357.     {
  358.     printf(" Filename:%s\n",temp);
  359.     printf(" Load Messages Error code %d\n",code);
  360.     };
  361.   }
  362. extern int       outPut;
  363. extern char      outFlag;
  364. extern char      Showing;
  365. extern char      ReverseMessage;
  366. extern char      pullMessage;
  367. extern int       thisRoom;
  368. extern char      journalMessage;
  369. extern char      MsgStreamEnter;
  370. extern char      echo;           /* Output flag  */
  371. extern char      echoChar;
  372. extern char      loggedIn;       /* Logged in flag      */
  373. extern SListBase Moderators;
  374. extern char      pause_whichMess;
  375. char  Pause_Message_Check()
  376.   {
  377.   /**
  378.     If this is a user, and the user has Pause at end of message
  379.     in their configuration, we will pause here asking for a character.
  380.     We will eat all input first(just incase of line noise).
  381.     A "S" will attempt to stop the message stream.
  382.     A "N" will attempt to skip to next message.
  383.     Basically, we duplicate MABORT() here...
  384.   **/
  385.    char c, toReturn, oldEcho;
  386.    toReturn = FALSE;
  387.    if( outFlag == IMPERVIOUS || outFlag == NET_CALL
  388.     || outPut == DISK )return toReturn;
  389.    if( loggedIn )
  390.      {
  391.      if( logBuf.lbflags.MSG_PAUSE
  392.       && ( ( pause_whichMess != NEWoNLY
  393.           && thisRoom == MAILROOM ) || thisRoom != MAILROOM) )
  394.        {
  395.        if( aide ||
  396.            ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  397.              && strLen(logBuf.lbname) != 0 ))
  398.          {
  399.          Output_Citadel_Message("SYSPAU",NULL, NULL, NULL);
  400.          }
  401.        Output_Citadel_Message("MSGPAU",NULL, NULL, NULL);
  402.        oldEcho = echo;
  403.        echo    = NEITHER;
  404.        echoChar= 0;
  405.        while (MIReady())   inp();   /* eat noise */
  406.        c = toUpper(modIn());        /* accept one character */
  407.        switch (c)
  408.          {
  409.          case 'D':  /* delete the message if you have privileges */
  410.            if( Showing == MSGS &&
  411.                ( aide ||
  412.                  ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  413.                  && strLen(logBuf.lbname) != 0)))
  414.               {
  415.               pullMessage = TRUE;
  416.               toReturn = TRUE;
  417.               };
  418.             break;
  419.           case 'S' : /* stop displaying messages */
  420.             outFlag  = OUTSKIP;
  421.             toReturn = TRUE;
  422.             break;
  423.          case 'J':  /* Journal the Message */
  424.            if( Showing == MSGS &&
  425.                ( aide ||
  426.                  ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  427.                  && strLen(logBuf.lbname) != 0 ) ) )
  428.               {
  429.               journalMessage = TRUE;
  430.               toReturn       = TRUE;
  431.               };
  432.             break;
  433.          case 'E':  /* Enter a Reply */
  434.             if( Showing == MSGS && HasWritePrivs())
  435.               {
  436.               MsgStreamEnter = TRUE;
  437.               outFlag        = OUTSKIP;
  438.               toReturn       = TRUE;
  439.               };
  440.             break;
  441.          case 'R':  /* Reverse the flow */
  442.             if( Showing == MSGS )
  443.               {
  444.               ReverseMessage = TRUE;
  445.               toReturn       = TRUE;
  446.               };
  447.             break;
  448.          };
  449.        echo = oldEcho;
  450.        }
  451.      else if( Showing == MSGS && thisRoom == MAILROOM && pause_whichMess == NEWoNLY)toReturn = TRUE;
  452.      };
  453.   return toReturn;
  454.   }
  455.